package com.chenju.invokechainservice.adapter;

import com.chenju.invokechainservice.common.enums.EasyCode;
import com.chenju.invokechainservice.utils.FunnyListsUtils;
import com.chenju.invokechainservice.utils.FunnyStringUtils;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.springframework.asm.Opcodes;

import java.util.ArrayList;
import java.util.List;

public class MethodNodeAdapter extends MethodNode {
    public List<MethodInsnNode> invokeMethods;
    public boolean isAdvice = false;
    public String adviceType = null;

    public MethodNodeAdapter(int access, String name, String descriptor, String signature, String[] exceptions) {
        super(Opcodes.ASM9);
        this.access = access;
        this.name = name;
        this.desc = descriptor;
        this.signature = signature;
        this.exceptions = FunnyListsUtils.asArrayList(exceptions);
        this.invokeMethods = new ArrayList<>();
    }

    @Override
    public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
        String annotationFullName = FunnyStringUtils.findDotString(Type.getType(descriptor).getClassName());
        if (EasyCode.adviceAnnotationList.contains(annotationFullName)){
            isAdvice = true;
            adviceType = FunnyStringUtils.findLastName(annotationFullName);
        }
        return super.visitAnnotation(descriptor, visible);
    }

    @Override
    public void visitMethodInsn(int opcodeAndSource, String owner, String name, String descriptor, boolean isInterface) {
        int opcode = opcodeAndSource & -257;
        MethodInsnNode invokeMethod = new MethodInsnNode(opcode, owner, name, descriptor, isInterface);
        if (owner.startsWith("com/chenju") && !"<init>".equals(name)) {
            if (!this.invokeMethods.contains(invokeMethod)){
                this.invokeMethods.add(invokeMethod);
            }
        }
    }
}
